/*
 * @Descripttion:
 * @Author: 张正兴
 * @Date: 2022-03-28 16:40:20
 * @LastEditors: 张正兴
 */
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
import * as THREE from "three";
import moment from "moment";
import { animations } from "../params";
import gsap from "gsap";
import LightMod from "../light/lightMod";

class Model {
  scene: any = {};

  constructor(scene: any) {
    this.scene = scene;
  }

  // 网格模型
  lodeModel(modelUrl: string, position: any, scale = [0.2, 0.2, 0.2], material?: any, castShadow = false) {
    const object: any = new THREE.Object3D();
    let objLoader = new FBXLoader();
    objLoader.load(modelUrl, (mesh: any) => {
      //模型已组的方式储存需要进行遍历
      mesh.children.forEach((node: any) => {
        node.castShadow = castShadow;
        node.receiveShadow = true;
      });

      mesh.children[1].layers.enable(1);
      mesh.children[2].layers.enable(1);
      mesh.children[3].layers.enable(1);

      if (material) {
        if (Array.isArray(material)) {
          for (let i = 0; i < mesh.children.length; i++) {
            mesh.children[i].material = material[i];
          }
        } else {
          mesh.children[0].material = material;
        }
      }

      mesh.scale.set(scale[0], scale[1], scale[2]);
      mesh.position.set(position[0], position[1], position[2]);
      object.add(mesh);
      this.scene.add(object);
    });
    return object;
  }

  // 动画模型
  animationModel(modelUrl: string, position: any, scale = [0.2, 0.2, 0.2], material?: any, castShadow = false) {
    const object: any = new THREE.Object3D();
    let objLoader = new FBXLoader();
    objLoader.load(modelUrl, (mesh: any) => {
      //模型已组的方式储存需要进行遍历
      mesh.children.forEach((node: any) => {
        node.castShadow = castShadow;
        node.receiveShadow = true;
      });

      // 动画
      const mixer = new THREE.AnimationMixer(mesh);
      mixer.clipAction(mesh.animations[0]).play();
      animations.push(mixer);

      mesh.children[2].layers.enable(1);
      mesh.children[3].layers.enable(1);
      mesh.children[4].layers.enable(1);

      if (material) {
        if (Array.isArray(material)) {
          for (let i = 0; i < mesh.children.length; i++) {
            mesh.children[i].material = material[i];
          }
        } else {
          mesh.children[0].material = material;
        }
      }

      mesh.scale.set(scale[0], scale[1], scale[2]);
      mesh.position.set(0, 0, 0);
      object.add(mesh);

      // const light = new LightMod();
      // const directionalLight = light.spotlight([0, 200, 0]);
      // object.add(directionalLight);

      let demo = { score: -300 };

      gsap.to(demo, {
        score: 300,
        ease: "linear", // 开启则匀速运动
        repeat: -1, // 重复次数
        onUpdate: showScore,
        duration: 120,
      });

      function showScore() {
        object.position.set(position[0], position[1], demo.score + position[2]);
      }

      this.scene.add(object);
    });
    return object;
  }

  // 加载精灵图
  sprite(position: any = [0, 0, 0], scale: any = [40, 40], size: any = [500, 500]) {
    // 设置canvas贴图
    const canvas = document.createElement("canvas");
    canvas.width = 500;
    canvas.height = 500;
    const c: any = canvas.getContext("2d");
    c.font = "bold 40px 微软雅黑";
    c.textBaseline = "middle";
    c.textAlign = "center";
    c.fillStyle = "#7e8eff";
    const img = new Image();
    img.src = "/img/datav.png";
    img.onload = function () {
      // 将图片画到canvas上面上去！
      c.drawImage(img, 0, 0, 500, 220);
    };

    const map = new THREE.TextureLoader().load("");
    const material = new THREE.SpriteMaterial({ map: map });

    setInterval(() => {
      const result = moment().format("yyyy-MM-DD HH:mm:ss");
      let texture = new THREE.CanvasTexture(canvas);
      c.clearRect(0, 0, 500, 500);
      c.drawImage(img, 0, 0, 500, 220);
      c.fillText(result, 260, 100);
      material.map = texture;
    }, 1000);

    // 创建精灵模型对象，不需要几何体geometry参数
    const sprite = new THREE.Sprite(material);

    sprite.position.set(position[0], position[1], position[2]);
    // 控制精灵大小，比如可视化中精灵大小表征数据大小
    sprite.scale.set(scale[0], scale[1], 0); // 只需要设置x、y两个分量就可以

    return sprite;
    // this.scene.add(sprite);
  }

  // 正方体
  BoxGeometry() {
    // 设置canvas贴图
    const canvas = document.createElement("canvas");
    canvas.width = 500;
    canvas.height = 500;
    const c: any = canvas.getContext("2d");
    c.font = "bold 48px 宋体";
    c.textBaseline = "middle";
    c.textAlign = "center";
    // const img = new Image();
    // img.src = "/img/datav.png";
    // if (c) {
    //   img.onload = function () {
    //     c.drawImage(img, 0, 0, 500, 220);
    //     c.fillStyle = "#ffffff";
    //     c.font = "bold 48px 宋体";
    //     c.textBaseline = "middle";
    //     c.textAlign = "center";
    //     c.fillText("我是冰敦敦", 200, 100);
    //   };
    // }
    let texture = new THREE.CanvasTexture(canvas);

    const sprit2: any = new THREE.TextureLoader().load("/img/guang.png");

    const material2 = new THREE.MeshBasicMaterial({ map: sprit2 });

    // const material1 = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide,color: '#7e8eff' });

    const geometry1 = new THREE.BoxGeometry(30, 30, 30);

    const mesh1 = new THREE.Mesh(geometry1, material2);
    mesh1.layers.enable(0);
    mesh1.position.set(30, 30, 30);
    this.scene.add(mesh1);
  }

  // 管道模型
  lineObj() {
    let map = new THREE.TextureLoader().load("/img/guangzhu.png");
    // 贴图重复
    map.wrapS = THREE.RepeatWrapping;
    map.wrapT = THREE.RepeatWrapping;
    // 贴图大小
    map.repeat.set(1, 1);
    let i = 0.015;
    setInterval(function () {
      i += 0.015;
      // 贴图偏移
      map.offset = new THREE.Vector2(i, 0);
    }, 50);

    const material = new THREE.MeshBasicMaterial({
      map: map,
      transparent: true,
      opacity: 1,
      color: "#7e8eff",
    });

    // 创建管道成型的路径(3D样条曲线)
    const path = new THREE.CatmullRomCurve3([
      new THREE.Vector3(-1000, 20, -150),
      new THREE.Vector3(100, 20, 0),
      new THREE.Vector3(200, 20, 100),
      new THREE.Vector3(1000, 20, 100),
    ]);

    // path:路径   40：沿着轨迹细分数  2：管道半径   25：管道截面圆细分数
    const geometry = new THREE.TubeGeometry(path, 50, 1, 3);
    const mesh = new THREE.Mesh(geometry, material);
    mesh.layers.enable(1);

    for (let i = 0; i < 5; i++) {
      let value = i * 6;
      const mesh1 = mesh.clone();
      mesh1.position.x = 200 + value;
      mesh1.position.y = value;
      this.scene.add(mesh1);
    }
  }
}

export default Model;
